﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO.Compression;
using System.Web.Script.Serialization;
using System.Drawing;

namespace LightingServer
{
    public static class SerializeHelper
    {
        public static string ConvertToJson(object instance)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            serializer.MaxJsonLength = 1024000;
            return serializer.Serialize(instance);
        }

        public static T ConvertFromJson<T>(string josh)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            serializer.MaxJsonLength = 1024000;
            return serializer.Deserialize<T>(josh);
        }

        public static byte[] ImageToByteArray(System.Drawing.Image imageIn)
        {
            byte[] data = null;
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                data = ms.ToArray();
            }
            return data;
        }

        public static byte[] Serilize(object instance)
        {
            byte[] array = null;
            using (Stream stream = new MemoryStream())
            {
                BinaryFormatter bformatter = new BinaryFormatter();

                Console.WriteLine("Writing Employee Information");
                bformatter.Serialize(stream, instance);
                stream.Flush();
                if (stream.CanRead)
                    stream.Position = 0;
                array = ReadFully(stream, 0);
                stream.Close();
            }
            return array;
        }

        public static Image StreamToImage(Stream ms)
        {
            return Image.FromStream(ms);
        }
       
        public static Image ByteArrayToImage(byte[] byteArrayIn)
        {
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image returnImage = Image.FromStream(ms);
            return returnImage;
        }

        public static byte[] ReadFully(Stream stream, int initialLength = 32768)
        {
            // If we've been passed an unhelpful initial length, just
            // use 32K.
            if (initialLength < 1)
            {
                initialLength = 32768;
            }

            byte[] buffer = new byte[initialLength];
            int read = 0;

            int chunk;
            stream.Position = 0;
            while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0)
            {
                read += chunk;

                // If we've reached the end of our buffer, check to see if there's
                // any more information
                if (read == buffer.Length)
                {
                    int nextByte = stream.ReadByte();

                    // End of stream? If so, we're done
                    if (nextByte == -1)
                    {
                        return buffer;
                    }

                    // Nope. Resize the buffer, put in the byte we've just
                    // read, and continue
                    byte[] newBuffer = new byte[buffer.Length * 2];
                    Array.Copy(buffer, newBuffer, buffer.Length);
                    newBuffer[read] = (byte)nextByte;
                    buffer = newBuffer;
                    read++;
                }
            }
            // Buffer is now too big. Shrink it.
            byte[] ret = new byte[read];
            Array.Copy(buffer, ret, read);
            return ret;
        }

        private static Object ByteArrayToObject(byte[] arrBytes)
        {
            var formatter = new BinaryFormatter();
            using (var ms = new MemoryStream(arrBytes))
            {
                using (var ds = new DeflateStream(ms, CompressionMode.Decompress, true))
                {
                    object o = formatter.Deserialize(ds);
                }
            }
            return null;
            //MemoryStream memStream = new MemoryStream();
            //BinaryFormatter binForm = new BinaryFormatter();
            //memStream.Write(arrBytes, 0, arrBytes.Length);
            //memStream.Seek(0, SeekOrigin.Begin);
            //object o = binForm.Deserialize(memStream);
            //Object obj = (Object)binForm.Deserialize(memStream);
            //return obj;
        }

        public static object DeSerilize(string str)
        {
            byte[] bytes = new byte[str.Length * sizeof(char)];
            System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
            return ByteArrayToObject(bytes);
        }
    }
}
